#include "exchange_brep.h"
#include "topology/TopoBuilder.hpp"
#include "topology/TopoCompound.hpp"
#include "occtio/OCCTTool.hpp"
#include "topology/TopoShape.hpp"
#include "common/system_log.h"
#include "utils/file_util.h"
#include "utils/string_util.h"
#include <iostream>
#include <fstream>
#include <memory>
#include "ExchangeTopoShape.h"


AMCAX_EXCHANGE_NAMESPACE_BEGIN

void ExchangeBrep::read_common(AMCAX::TopoShape &shape)
{
    std::shared_ptr<ExchangeObject> exchange_shape(new ExchangeObject(string_util::generate_UUID()));
    exchange_shape->shape = std::make_shared<ExchangeTopoShape>(shape);
    exchange_shape->name = "brep";
    exchangeObjectList_.push_back(exchange_shape);
}

void ExchangeBrep::ReadFromFilePath() {
#ifdef AMCAX_BREP_ENABLE
    AMCAX::TopoShape shape ;
    if (!AMCAX::Exchange::file_util::is_file_exist(filePath_)) {
        LOG_ERROR("file not exist:{}",filePath_) ;
        return ;
    }
    AMCAX::OCCTIO::OCCTTool::Read(shape, filePath_);
    read_common(shape);
#endif
}


void ExchangeBrep::ReadFromFileStream() {
    #ifdef AMCAX_BREP_ENABLE
    if(nullptr == inFileStream_){
        LOG_ERROR("input file stream is null") ;
        return ;
    }
    AMCAX::TopoShape shape ;
    std::istream* inputStream = &(*inFileStream_);
    AMCAX::OCCTIO::OCCTTool::Read(shape, *inputStream);
    read_common(shape);
    #endif
}

void ExchangeBrep::Write(const std::vector<std::shared_ptr<ExchangeObject>>& exchange_shapes, const std::shared_ptr<ExchangeDocumentInstance> &exchangeDocumentInstance)
{
    #ifdef AMCAX_BREP_ENABLE
    AMCAX::TopoBuilder builder;
    AMCAX::TopoCompound comp;
    builder.MakeCompound(comp);

    std::vector<std::shared_ptr<ExchangeObject>> flatShapes;
    NestedExchangeShapeToFlat(flatShapes, exchange_shapes); 
    // for (auto &top_shape : exchange_shapes) {
    //     flatShapes.push_back(top_shape) ;
    //     NestedExchangeShapeToFlat(flatShapes, top_shape); 
    // }

    for (auto exData : flatShapes) 
    {
        if (!exData->shape->GetShape().IsNull())
        {
                builder.Add(comp, exData->shape->GetShape());
        }
    }

    if (OUTPUT_FILE_TYPE::FILE_PATH == outputFileType_) {
        if (AMCAX::Exchange::file_util::is_file_exist(filePath_))
        {
            LOG_ERROR("file<{}> already exist",filePath_) ;
            return ;
        }
       AMCAX::OCCTIO::OCCTTool::Write(comp, filePath_, false);
    }
    else if (OUTPUT_FILE_TYPE::FILE_OUTPUT_STREAM == outputFileType_) 
    {
        if(nullptr == outFileStream_) {
            LOG_ERROR("outFileStream_ is null") ;
            return  ;
        }
        AMCAX::OCCTIO::OCCTTool::Write(comp, *outFileStream_, false);
    }else {
        LOG_ERROR("output file type:{} is unknown",(int)outputFileType_) ;
        return ;
    }
    #endif
}


AMCAX_EXCHANGE_NAMESPACE_END